/**
 * @descript 对 uni-app 一些 api 的封装，为了方便使用
 *
 * @author 济南晨霜信息技术有限公司
 * @mobile 18560000860 / 18754137913
 *
 * @list 函数列表
 * ========================================================================================================================
 * = uniGetNodeRectInfo    : 获取单个节点布局信息
 * = uniGetNodesRectInfo   : 获取多个节点节点布局信息
 * = uniGetPagesData       : 获取所有在 pages.json 中定义的页面数据
 * = uniGetTabBarData      : 获取在 pages.json 中定义的 tabBar 数据
 * = uniGetPageData        : 获取指定页面在 pages.json 中定义的数据
 * = uniGetCurrentPageData : 获取当前页面在 pages.json 中定义的数据
 * = uniIsTabBar           : 判断当前页面或指定页面路径对应的页面是否是 tabBar 页面
 * = uniIsPageExist        : 判断页面是否在 pages.json 中定义
 * ========================================================================================================================
 */
import pagesJson from "@/pages.json";
import { urlGetMainPart } from "./url";

/**
 * 获取单个节点布局信息
 * @param {String} selector 节点 id 或 class
 * @param {getCurrentInstance} instance 组件实例
 * Tips: 需要在上方定义成 const instance = getCurrentInstance() 后传递 instance，否则直接传递 getCurrentInstance() 不生效，实际开发中遇到的，不知道是啥原因
 * @returns {Object} 节点布局信息；
 */
export const uniGetNodeRectInfo = (selector, instance) => {
    return new Promise((resolve) => {
        uni.createSelectorQuery()
            .in(instance)
            .select(selector)
            .boundingClientRect((data) => {
                resolve(data);
            })
            .exec();
    });
};

/**
 * 获取多个节点节点布局信息
 * @param {String} selector 节点 id 或 class
 * @param {getCurrentInstance} instance 组件实例
 * Tips: 需要在上方定义成 const instance = getCurrentInstance() 后传递 instance，否则直接传递 getCurrentInstance() 不生效，实际开发中遇到的，不知道是啥原因
 * @returns {Array} 节点布局信息；
 */
export const uniGetNodesRectInfo = (selector, instance) => {
    return new Promise((resolve) => {
        uni.createSelectorQuery()
            .in(instance)
            .selectAll(selector)
            .boundingClientRect()
            .exec((data) => {
                resolve(data?.[0] || []);
            });
    });
};

/**
 * 获取所有在 pages.json 中定义的页面数据
 * Tips: 包含主包和所有分包
 * @returns {Array} 返回在 pages.json 中定义的页面数据，包含主包和所有分包
 */
export const uniGetPagesData = () => {
    // 返回的数据
    const pages = [];

    // 主包页面数据
    const mainPages = pagesJson?.pages || [];

    // 分包数据
    const subPackages = pagesJson?.subPackages || [];

    // 1. 先处理主包页面数据
    mainPages.forEach((page) => {
        // 为了统一，为主包和分包页面数据增加 fullPath 字段，表示开头为 "/" 的完整的（带分包根目录路径的）页面路径
        page.fullPath = `/${page.path}`;

        // 将页面数据添加到总页面数据中
        pages.push(page);
    });

    // 2. 再处理分包数据
    subPackages.forEach((subPackage) => {
        // 分包的根目录
        const root = subPackage?.root || "";

        // 分包中的页面数据
        const subPages = subPackage?.pages || [];

        // 处理分包中的页面数据
        subPages.forEach((subPage) => {
            // 为了统一，为主包和分包页面数据增加 fullPath 字段，表示开头为 "/" 的完整的（带分包根目录路径的）页面路径
            subPage.fullPath = `/${root}/${subPage.path}`;

            // 将页面数据添加到总页面数据中
            pages.push(subPage);
        });
    });

    // 最后返回总页面数据
    return pages;
};

/**
 * 获取在 pages.json 中定义的 tabBar 数据
 * @returns {Object} 返回在 pages.json 中定义的 tabBar 数据对象或 null
 */
export const uniGetTabBarData = () => pagesJson?.tabBar || null;

/**
 * 获取指定页面在 pages.json 中定义的数据
 * @param {String} url 指定页面URL
 * @returns {Object} 指定页面在 pages.json 中定义的数据
 */
export const uniGetPageData = (url = "") => {
    const pages = uniGetPagesData();
    const urlMainPart = urlGetMainPart(url);
    return pages.find((item) => urlMainPart === item?.fullPath || urlMainPart === `/${item?.fullPath}`);
};

/**
 * 获取当前页面在 pages.json 中定义的数据
 * @return {Object} 返回当前页面在 pages.json 中定义的数据
 */
export const uniGetCurrentPageData = () => {
    const pages = getCurrentPages();
    const page = pages[pages.length - 1];
    return uniGetPageData(page?.$page?.fullPath);
};

/**
 * 判断当前页面或指定页面路径对应的页面是否是 tabBar 页面
 * @param {String} pagePath 页面路径，如果该参数为空，那么判断当前页面是否是 tabBar 页面
 * @returns {Boolean} true: 是 tabBar 页面； false: 不是 tabBar 页面；
 */
export const uniIsTabBar = (pagePath = "") => {
    // TabBar 页面数据
    const tabBarList = uniGetTabBarData()?.list || [];

    // 1. 传入的参数值不为空
    if (pagePath) {
        // 传入的页面路径问号（?）之前的部分
        const urlMainPart = urlGetMainPart(pagePath);

        // 判断并返回该路径对应的页面是否是 tabBar 页面
        return tabBarList.find((item) => urlMainPart === item?.pagePath || urlMainPart === `/${item?.pagePath}`);
    }

    // 2. 传入的参数为空
    // 获取当前页面在 pages.json 中定义的数据
    const currentPageData = uniGetCurrentPageData();

    // 判断并返回当前页面是否是 tabBar 页面
    return tabBarList?.find((item) => `/${item.pagePath}` === currentPageData?.fullPath);
};

/**
 * 判断页面是否在 pages.json 中定义
 * @param {String} pagePath 页面路径
 * @returns {Boolean} true: 页面存在；false: 页面不存在；
 */
export function uniIsPageExist(pagePath) {
    if (!pagePath) return false;
    const urlMainPart = urlGetMainPart(pagePath);
    const pages = uniGetPagesData();
    return pages.find((item) => item.fullPath === urlMainPart || item.fullPath === `/${urlMainPart}`);
}
